package org.jradweb.tools.generator.freemarker;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.maven.plugin.logging.Log;
import org.jradweb.core.utils.DateFormat;
import org.jradweb.tools.generator.FileAlreadyExistsException;
import org.jradweb.tools.generator.FileOperatorException;
import org.jradweb.tools.generator.FreemarkerTemplateExcepion;
import org.jradweb.tools.generator.freemarker.util.FileGenerator;
import org.jradweb.tools.generator.freemarker.util.Templates;
import org.jradweb.tools.generator.utils.LogImpl;
import org.jradweb.tools.generator.utils.StringUtils;

/**
 * for generate java class file
 * 
 * Created On 2008-2-28
 * 
 * @author <a href="mailto:wagzhi@gmail.com">Paul Wang</a>
 * @version $Id: ClassGenerator.java 148 2008-10-10 03:07:23Z wagzhi $
 */
public class ClassGenerator {
	protected Log log;
	protected String groupId;
	protected String artifactId;

	protected String srcPath;
	protected String testPath;
	protected String projectPackagePath;

	protected Map<String, Object> params;

	/**
	 * 
	 * @param projectRootPath
	 * @param groupId
	 * @param artifactId
	 * @param log
	 */
	public ClassGenerator(File projectRootPath, String groupId,
			String artifactId, Log log) {
		this.groupId = groupId;
		this.artifactId = artifactId;
		this.log = log;

		srcPath = projectRootPath.getAbsolutePath() + "/src/main/java";
		testPath = projectRootPath.getAbsolutePath() + "/src/test/java";
		projectPackagePath = srcPath + "/" + StringUtils.packageToPath(groupId)
				+ "/" + artifactId.toLowerCase();
		Date createdTime = new Date();
		params = new HashMap<String, Object>();
		params.put("createdTime", createdTime.toString());
		params.put("createdAt", DateFormat.formatDateTime(createdTime));
		params.put("groupId", this.groupId);
		params.put("artifactId", this.artifactId);
	}

	public boolean createModelClass(String modelName)
			throws FileOperatorException, FileAlreadyExistsException,
			FreemarkerTemplateExcepion {
		String model = StringUtils.upperCaseFirst(modelName);

		params.put("modelName", model);
		params.put("modelTableName", StringUtils.lowerCaseName(model));

		File dist = new File(this.projectPackagePath + "/model/" + model
				+ ".java");

		if (dist.exists()) {
			log.warn("File " + dist.getAbsolutePath() + " already exists!");
			return false;
		}

		FileGenerator.writeFile(dist, params, Templates.MODEL_TEMPLATE, false);
		log.info("File " + dist.getAbsolutePath() + " created successfully!");
		return true;
	}

	public boolean createDao(String modelName) throws FileOperatorException,
			FileAlreadyExistsException, FreemarkerTemplateExcepion {
		String model = StringUtils.upperCaseFirst(modelName);

		params.put("modelName", model);
		File daoFile = new File(this.projectPackagePath + "/dao/" + model
				+ "Dao.java");

		File daoImplFile = new File(this.projectPackagePath + "/dao/impl/"
				+ model + "DaoImpl.java");

		if (daoFile.exists()) {
			log.warn("File " + daoFile.getAbsolutePath() + " already exists!");
			return false;
		}

		FileGenerator.writeFile(daoFile, params, Templates.DAO_TEMPLATE, false);

		log
				.info("File " + daoFile.getAbsolutePath()
						+ " created successfully!");
		return true;
	}

	public boolean createService(String serviceName, String modelName,boolean force)
			throws FileOperatorException, FileAlreadyExistsException,
			FreemarkerTemplateExcepion {
		
		Value service=new Value(serviceName);
		Value model=new Value(modelName);
		params.put("service", service);
		params.put("model", model);

		File serviceFile = new File(this.projectPackagePath + "/service/"
				+ service + "Service.java");
		
		try {
			FileGenerator.writeFile(serviceFile, params,
					Templates.SERVICE_TEMPLATE, force);
		} catch (FileAlreadyExistsException e) {
			log.warn("File " + serviceFile.getAbsolutePath()
					+ " already exists!");
			return false;
		}

		log.info("File " + serviceFile.getAbsolutePath()
				+ " created successfully!");

		return true;
	}

	public boolean createAbstractService(String serviceName, String modelName,boolean force)
			throws FileOperatorException, FileAlreadyExistsException,
			FreemarkerTemplateExcepion {
		
		Value service=new Value(serviceName);
		Value model=new Value(modelName);
		params.put("service", service);
		params.put("model", model);

		File serviceFile = new File(this.projectPackagePath
				+ "/service/Abstract" + service + "Service.java");
		
		try {
			FileGenerator.writeFile(serviceFile, params,
					Templates.SERVICE_ABSTRACT_TEMPLATE, force);
		} catch (FileAlreadyExistsException e) {
			log.warn("File " + serviceFile.getAbsolutePath()
					+ " already exists!");
			return false;
		}

		log.info("File " + serviceFile.getAbsolutePath()
				+ " created successfully!");

		return true;
	}

	public boolean createServiceImpl(String serviceName, String modelName,
			boolean force) throws FileOperatorException,
			FileAlreadyExistsException, FreemarkerTemplateExcepion {
		Value service =new Value(serviceName);
		Value model=new Value(modelName);
		params.put("service", service);
		params.put("model", model);

		File serviceFile = new File(this.projectPackagePath + "/service/impl/"
				+ service + "ServiceImpl.java");

		try {
			FileGenerator.writeFile(serviceFile, params,
					Templates.SERVICE_IMPL_TEMPLATE, force);
		} catch (FileAlreadyExistsException e) {
			log.warn("File " + serviceFile.getAbsolutePath()
					+ " already exists!");
			return false;
		}

		log.info("File " + serviceFile.getAbsolutePath()
				+ " created successfully!");

		return true;
	}

	public boolean createDaoImpl(String modelName)
			throws FileOperatorException, FileAlreadyExistsException,
			FreemarkerTemplateExcepion {
		String model = StringUtils.upperCaseFirst(modelName);

		params.put("modelName", model);

		File daoImplFile = new File(this.projectPackagePath + "/dao/impl/"
				+ model + "DaoImpl.java");

		if (daoImplFile.exists()) {
			log.warn("File " + daoImplFile.getAbsolutePath()
					+ " already exists!");
			return false;
		}

		FileGenerator.writeFile(daoImplFile, params,
				Templates.DAO_IMPL_TEMPLATE, false);

		log.info("File " + daoImplFile.getAbsolutePath()
				+ " created successfully!");
		return true;
	}

	public boolean createController(String controllerName, String modelName,
			String serviceName,boolean force) throws FileOperatorException,
			FileAlreadyExistsException, FreemarkerTemplateExcepion {
		Value controller=new Value(controllerName);
		Value model=new Value(modelName);
		Value service=new Value(serviceName);
		params.put("controller", controller);
		params.put("model", model);
		params.put("service", service);

		File dist = new File(this.projectPackagePath + "/controller/"
				+ controller + "Controller.java");

		try {
			FileGenerator.writeFile(dist, params, Templates.CONTROLLER_TEMPLATE,
					force);
		} catch (FileAlreadyExistsException e) {
			log.warn("File " + dist.getAbsolutePath() + " already exists!");
			return false;
		}
		log.info("File " + dist.getAbsolutePath() + " created successfully!");

		return true;
	}

	public static void main(String[] args) throws Exception {
		List<Value> models = new ArrayList<Value>();
		String model = "Customer";
		models.add(new Value(model));

		try {
			File projectRootPath = new File("D:/workspace2/jradtest");
			ClassGenerator cg = new ClassGenerator(projectRootPath,
					"org.jradweb", "jradtest",
					new LogImpl(ClassGenerator.class));
			cg.createModelClass(model);
			cg.createDao(model);
			cg.createDaoImpl(model);
			cg.createService(model, model,true);
			cg.createAbstractService(model, model,true);
			cg.createServiceImpl(model, model, true);
			cg.createController(model, model, model,true);
		} catch (FileOperatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileAlreadyExistsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FreemarkerTemplateExcepion e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
